<template>
  <section class="comments__wrapper">
    <!-- 留言区的发布组件 -->
    <div class="leave-comment" v-if="placeTop">
      <a-input
        ref="commentRef"
        v-model:value="content"
        :placeholder="`发表${topic}`"
      ></a-input>
      <a-button
        class="btn-publish"
        type="primary"
        v-throttle="{
          func: onClickPublish,
          wait: 1500,
          type: 'click',
        }"
        >发布</a-button
      >
    </div>
    <!-- 如果有评论区内容就显示区域,使用指令无限滚动 -->
    <div
      class="comments__body"
      v-infinite-scroll="loadMore"
      infinite-scroll-distance="400"
      :infinite-scroll-disabled="!autoLoad"
    >
      <ul class="comments__list" v-if="comments.length > 0">
        <li v-for="comment in comments" :key="comment.id">
          <!-- 评论卡组件,已经遍历了,所以传进一个聚焦的值就好了 -->
          <card-comments
            :comment="comment"
            @UserInfoisEmpty="remindCreateUserInfo"
            @setActive="onSetActive"
            :isActive="activeid === comment.id"
          />
        </li>
      </ul>

      <a-empty v-else-if="!isFetchloading">
        <template #description>
          <span> 暂无{{ topic }},快来聊骚吧! </span>
          <a-button class="btn-add" type="primary" @click="createComment">
            创建{{ topic }}
          </a-button>
        </template>
      </a-empty>

      <a-skeleton active :paragraph="{ rows: 3 }" :loading="isFetchloading" />

      <!-- 自制版见底加载 -->

      <bottom-tips v-if="comments.length < total">
        <a-button shape="round" type="primary" @click="loadMore">
          加载更多
        </a-button>
      </bottom-tips>
      <bottom-tips v-else-if="total > 0" content="没有更多了" />
    </div>

    <!-- 评论区的发布组件 -->
    <div class="leave-comment" v-if="!placeTop">
      <a-input
        ref="commentRef"
        v-model:value="content"
        :placeholder="`发表${topic}`"
      ></a-input>
      <a-button
        class="btn-publish"
        type="primary"
        v-throttle="{
          func: onClickPublish,
          wait: 1500,
          type: 'click',
        }"
        >发布</a-button
      >
    </div>

    <a-modal
      v-model:visible="ismodalVisible"
      title="用户信息"
      class="align-center"
      :footer="null"
    >
      <comments-user-info @cancel="ismodalVisible = false" />
    </a-modal>
  </section>
</template>

<script lang="ts">
import { Input, message, Modal } from 'ant-design-vue';
import { computed, defineComponent, reactive, ref, watchEffect } from 'vue';
import { useStore } from '@/store';
import CommentsUserInfo from './commentsUserInfo.vue';
import { useAsyncLoading } from '@/hooks';
import DOMPurify from 'dompurify';
import { commentService } from '@/api/comment';
import { CommentDTO, CommentUserInfo } from '@/bean/dto';
import { pageSize } from '@/config/config';
import CardComments from '../../../components/card/card-comments.vue';

export default defineComponent({
  name: 'Comments',
  props: {
    articleId: {
      type: Number,
    },
    topic: {
      type: String,
      default: '评论',
    },
    placeTop: {
      type: Boolean,
      default: false,
    },
    autoLoad: {
      type: Boolean,
      default: true,
    },
  },
  components: {
    [Input.name]: Input,
    [Modal.name]: Modal,
    CommentsUserInfo,
    CardComments,
  },
  setup(props) {
    // vuex

    const store = useStore();
    const commentsUserInfo = computed(() => store.state.commentUserInfo);

    const comments = ref<CommentDTO[]>([]);
    const commentRef = ref();
    const content = ref('');
    const ismodalVisible = ref(false);

    const remindCreateUserInfo = () => {
      message.warning(
        `请在${props.topic}前填写部分必要信息，我们不会公开您的私密信息！`
      );
      ismodalVisible.value = true;
    };

    // 聚焦输入框
    const createComment = () => {
      commentRef.value.focus();
    };

    async function handlePublish() {
      if (!commentsUserInfo.value) {
        remindCreateUserInfo();
        return;
      }
      // 如果有用户信息后走下一条
      if (!content.value) {
        // 必填校验
        message.warn('哥,没写评论呢...');
        return;
      }

      // 防止xxs注入攻击
      let clean = DOMPurify.sanitize(content.value);
      if (!clean) {
        // 输入了非法的内容
        message.warning('您的输入内容无效，请重新输入合法内容！');
        return;
      }

      const params = {
        // 用article_id来区分是留言板还是文章评论，留言是没有文章id的，而文章评论是有的
        article_id: props.articleId,

        content: clean,
        // 默认是未审核状态
        approved: 1,
        // 回访url,这玩意是啥啊
        jump_url: window.location.href,
        // 用户信息
        ...(store.state.commentUserInfo as CommentUserInfo),
      };

      // 判断完 将参数写进后台
      await commentService.add(params);
      content.value = '';
      message.success(`您的${props.topic}已经提交成功，待审核后即可生效！`);
    }

    const { trigger: onClickPublish, loading } = useAsyncLoading(handlePublish);

    // 获取数据
    const pageInfo = reactive({
      pageNo: 1,
      pageSize,
    });
    const total = ref(0);

    const flag = ref(true);
    const handleGetComments = async () => {
      // 这里要做优化,因为留言和评论两个组件复用在一起,但是我不知道评论是怎么搞的,所以先加上吧
      const res = await commentService.page({
        ...pageInfo,
        id: props.articleId,
      });

      if (res.data.length === 0) {
        flag.value = false;
      }
      comments.value = [...comments.value, ...res.data];
      total.value = res.total;
    };

    const { trigger: onGetComments, loading: isFetchloading } =
      useAsyncLoading(handleGetComments);

    watchEffect(() => {
      onGetComments();
    });

    const loadMore = () => {
      if (flag.value) {
        pageInfo.pageNo++;
      }
    };

    /* 回复哪个id */

    const activeid = ref(-1);
    const onSetActive = (id: number) => {
      activeid.value = id;
    };

    return {
      comments,
      content,
      loadMore,
      ismodalVisible,
      onClickPublish,
      createComment,
      commentRef,
      total,
      isFetchloading,
      remindCreateUserInfo,
      onSetActive,
      activeid,
    };
  },
});
</script>

<style scoped lang="scss">
.comments__wrapper {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.comments__body {
  overflow: auto;
  flex: 1;
  padding: 20px;
}

.leave-comment {
  display: flex;
  align-items: center;
  padding: 12px 20px;
  box-shadow: 0 -1px 10px 0 rgba(0, 0, 0, 0.1);
  z-index: 2;
}

.comments__list {
  > li + li {
    margin-top: 20px;
  }
}

:deep(.btn-add) {
  margin: 20px auto;
  display: block;
}
:deep(.btn-publish) {
  margin-left: 10px;
}
</style>
